#include "BaseThirdPersonCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedPlayerInput.h"
#include "EnhancedInputSubsystems.h"
#include "InputMappingContext.h"

ABaseThirdPersonCharacter::ABaseThirdPersonCharacter()
{
	GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);

	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;

	GetCharacterMovement()->bOrientRotationToMovement = true;
	GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f);
	GetCharacterMovement()->JumpZVelocity = 600.f;
	GetCharacterMovement()->AirControl = 0.2f;

	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(RootComponent);
	CameraBoom->TargetArmLength = 300.0f;
	CameraBoom->bUsePawnControlRotation = true;

	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
	FollowCamera->bUsePawnControlRotation = false;
}

//////////////////////////////////////////////////////////////////////////
// Input

void ABaseThirdPersonCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
	UEnhancedInputComponent* PlayerEnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
	if (PlayerEnhancedInputComponent)
	{
		// 有多种方法可以将 UInputAction* 绑定给回调函数，并且有多个关联的 ETriggerEvent。

		// MyInputAction 开始后，此处会在每次tick时调用回调函数（例如按下某个操作按钮时）
		// if (MyInputAction)
		// {
		// 	PlayerEnhancedInputComponent->BindAction(MyInputAction, ETriggerEvent::Started, this, &AMyPawn::MyInputHandlerFunction);
		// }

		// 只要输入条件满足（例如按住某个方向键），此处会按名称在每次tick时调用回调函数（UFUNCTION）。
		// if (MyOtherInputAction)
		// {
		// 	PlayerEnhancedInputComponent->BindAction(MyOtherInputAction, ETriggerEvent::Triggered, this, TEXT("MyOtherInputHandlerFunction"));
		// }
		// UInputAction* Action = FInputTestHelper::FindAction(this, TEXT("Jump"));
		// PlayerEnhancedInputComponent->BindAction(UInputAction::ActionsWithModifiedValueTypes.Find("Jump"), ETriggerEvent::Started, this, TEXT("Jump"));
		// UInputAction* MyAction = LoadObject<UInputAction>(nullptr, TEXT("InputAction'/Game/ThirdPerson/ThirdPersonCPP/Blueprints/JumpAction.JumpAction'"));
		// if(MyAction)
		// {
		// 		PlayerEnhancedInputComponent->BindAction(MyAction, ETriggerEvent::Ongoing, this, &ABaseThirdPersonCharacter::MyFirstAction);
		// }
		// PlayerEnhancedInputComponent->BindAction("MoveForward", ETriggerEvent::Ongoing, this, &ABaseThirdPersonCharacter::MoveForward);
		// PlayerEnhancedInputComponent->BindAction("MoveRight", ETriggerEvent::Ongoing, this, &ABaseThirdPersonCharacter::MoveRight);
		// InputAction'/Game/ThirdPerson/ThirdPersonCPP/Blueprints/JumpAction.JumpAction'
		// InputAction'/Game/ThirdPerson/ThirdPersonCPP/Blueprints/RunAction.RunAction'
	}
}

void ABaseThirdPersonCharacter::MoveForward(float Value)
{
	if ((Controller != NULL) && (Value != 0.0f))
	{
		// find out which way is forward
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		// get forward vector
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		AddMovementInput(Direction, Value);
	}
}

void ABaseThirdPersonCharacter::MoveRight(float Value)
{
	if ((Controller != NULL) && (Value != 0.0f))
	{
		// find out which way is right
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		// get right vector 
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
		// add movement in that direction
		AddMovementInput(Direction, Value);
	}
}

void ABaseThirdPersonCharacter::PawnClientRestart()
{
	Super::PawnClientRestart();
	// APlayerController* PC = Cast<APlayerController>(GetController());
	// if (PC)
	// {
	// 	// 从玩家控制器关联的本地玩家获取增强输入本地玩家子系统系统（Enhanced Input Local Player Subsystem）。
	// 	UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer());
	// 	if (Subsystem)
	// 	{
	// 		// PawnClientRestart可以在Actor的生命周期内执行多次，所以记得先清空可能遗留的映射。
	// 		Subsystem->ClearAllMappings();
	// 		UInputMappingContext* MyInputMappingContext = LoadObject<UInputMappingContext>(nullptr, TEXT("InputMappingContext'/Game/ThirdPerson/ThirdPersonCPP/Blueprints/JumpContext.JumpContext'"));
	// 		// 添加每个映射上下文以及它们的优先级数值。数值高意味着优先级更高。
	// 		if(MyInputMappingContext)
	// 		{
	// 			// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__"  MyInputMappingContext Valid."));
	// 			Subsystem->AddMappingContext(MyInputMappingContext, 1);
	// 		}else
	// 		{
	// 			// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__"  MyInputMappingContext InValid."));
	// 		}
	// 		
	// 	}else
	// 	{
	// 		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__"  UEnhancedInputLocalPlayerSubsystem InValid."));
	// 	}
	// }else
	// {
	// 	// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__"  APlayerController InValid."));
	// }
}
